package common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;

public class Utils {
	
	private static final String archiveSuffix = ".tar";
	private static final String compressSuffix = ".gz";
	
	
	
	/**
	 * 归档 
	 * @param file
	 * @return 最后压缩的文件路径
	 * @author yutao
	 * @param packageName 
	 * @date 2017年6月1日上午10:31:39
	 */
	public static String archive(File file, List<String> packageName){
		TarArchiveOutputStream tos = null;
		try {
			tos = new TarArchiveOutputStream(new FileOutputStream(file.getParent() + File.separator + file.getName() + archiveSuffix));
			String base = file.getName();
			if(file.isDirectory()){
				archiveDir(file, tos, base, packageName);
			}else{
				archiveHandle(tos, file, base);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(tos != null){
					tos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return file.getAbsolutePath() + archiveSuffix;
	}
	
	/**
	 * 归档
	 * @param entry
	 * @throws IOException
	 * @author yutao
	 * @return 
	 * @date 2017年5月27日下午1:48:23
	 */
	public static String archive(String filePath, List<String> packageName) {
		File file = new File(filePath);
		return archive(file, packageName);
	}

	/**
	 * 递归处理，准备好路径
	 * @param file
	 * @param tos
	 * @param base 
	 * @throws IOException
	 * @author yutao
	 * @param packageName 
	 * @date 2017年5月27日下午1:48:40
	 */
	private static void archiveDir(File file, TarArchiveOutputStream tos, String basePath, final List<String> packageName) throws IOException {
		File[] listFiles = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				if(packageName.contains(name)){
					return true;
				}
				return false;
			}
		});
		
		if(listFiles.length < 1){//这个是为了即便是空目录也会被创建
			TarArchiveEntry tEntry = new TarArchiveEntry(basePath + File.separator + file.getName());
			tos.putArchiveEntry(tEntry);
			tos.closeArchiveEntry();
		}
		
		for(File fi : listFiles){
			if(fi.isDirectory()){
				archiveDir(fi, tos, basePath + File.separator + fi.getName(), packageName);
			}else{
				archiveHandle(tos, fi, basePath);
			}
		}
	}

	/**
	 * 具体归档处理（文件）
	 * @param tos
	 * @param fi
	 * @param base
	 * @throws IOException
	 * @author yutao
	 * @date 2017年5月27日下午1:48:56
	 */
	private static void archiveHandle(TarArchiveOutputStream tos, File fi, String basePath) throws IOException {
		TarArchiveEntry tEntry = new TarArchiveEntry(basePath + File.separator + fi.getName());
		tEntry.setSize(fi.length());
		
		tos.putArchiveEntry(tEntry);
		
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fi));
		
		byte[] buffer = new byte[1024];
		int read = -1;
		while((read = bis.read(buffer)) != -1){
			tos.write(buffer, 0 , read);
		}
		bis.close();
		tos.closeArchiveEntry();
	}

	
	/**
	 * 把文件或目录打包压缩成tar.gz
	 * @param path
	 * @throws IOException
	 * @author yutao
	 * @return 
	 * @date 2017年5月27日下午2:08:37
	 */
	public static String compressArchive(String filePath, List<String> packageName) throws IOException{
		return compressArchive(new File(filePath), packageName);
	}
	
	/**
	 * 把文件或目录打包压缩成tar.gz
	 * @param path
	 * @throws IOException
	 * @author yutao
	 * @param packageName 
	 * @return 
	 * @date 2017年5月27日下午2:08:37
	 */
	public static String compressArchive(File file, List<String> packageName) throws IOException{
		String archivePath = archive(file, packageName);
		
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(archivePath));
		
		GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(new BufferedOutputStream(new FileOutputStream(archivePath + compressSuffix)));
		
		byte[] buffer = new byte[1024];
		int read = -1;
		while((read = bis.read(buffer)) != -1){
			gcos.write(buffer, 0, read);
		}
		gcos.close();
		bis.close();
		new File(archivePath).delete();
		return archivePath + compressSuffix;
	}
}
